library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
use work.global_definition.all;


entity ALU_CTRL is
    port (
        OP    : in  std_ulogic_vector(5 downto 0) := "000000";
        ALUOP : out std_ulogic_vector(3 downto 0) := "0000";
		  ALU_IN_A : out std_ulogic := '0';
		  ALU_IN_B : out std_ulogic := '0'
        );
end ALU_CTRL;

architecture Behavioral of ALU_CTRL is
begin
    process(OP)
    begin
        case OP is
				when OP_ADDIU   => 
				 ALUOP <= ALUOP_ADD;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '1';
				when OP_ADDIU3   => 
				 ALUOP <= ALUOP_ADD;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '1';
				when OP_ADDSP3   => 
				 ALUOP <= ALUOP_ADD;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '1';
				when OP_ADDSP   => 
				 ALUOP <= ALUOP_ADD;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '1';
				when OP_ADDU   => 
				 ALUOP <= ALUOP_ADD;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '0';
				when OP_AND   => 
				 ALUOP <= ALUOP_AND;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '0';
				when OP_B   => 
				 ALUOP <= ALUOP_REG1;
				 ALU_IN_A <= '1';
				 ALU_IN_B <= '1';
				when OP_BEQZ   => 
				 ALUOP <= ALUOP_REG1;
				 ALU_IN_A <= '1';
				 ALU_IN_B <= '1';
				when OP_BNEZ   => 
				 ALUOP <= ALUOP_REG1;
				 ALU_IN_A <= '1';
				 ALU_IN_B <= '1';
				when OP_BTEQZ   => 
				 ALUOP <= ALUOP_REG1;
				 ALU_IN_A <= '1';
				 ALU_IN_B <= '1';
				when OP_BTNEZ   => 
				 ALUOP <= ALUOP_REG1;
				 ALU_IN_A <= '1';
				 ALU_IN_B <= '1';
				when OP_CMP   => 
				 ALUOP <= ALUOP_SUB;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '0';
				when OP_CMPI   => 
				 ALUOP <= ALUOP_SUB;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '1';
				when OP_INT   => 
				 ALUOP <= ALUOP_REG1;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '0';
				when OP_JALR   => 
				 ALUOP <= ALUOP_REG1;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '0';
				when OP_JR   => 
				 ALUOP <= ALUOP_REG1;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '0';
				when OP_JRRA   => 
				 ALUOP <= ALUOP_REG1;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '0';
				when OP_LI   => 
				 ALUOP <= ALUOP_REG2;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '1';
				when OP_LW   => 
				 ALUOP <= ALUOP_ADD;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '1';
				when OP_LW_SP   => 
				 ALUOP <= ALUOP_ADD;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '1';
				when OP_MFIH   => 
				 ALUOP <= ALUOP_REG1;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '0';
				when OP_MFPC   => 
				 ALUOP <= ALUOP_REG1;
				 ALU_IN_A <= '1';
				 ALU_IN_B <= '0';
				when OP_MOVE   => 
				 ALUOP <= ALUOP_REG1;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '0';
				when OP_MTIH   => 
				 ALUOP <= ALUOP_REG1;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '0';
				when OP_MTSP   => 
				 ALUOP <= ALUOP_REG1;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '0';
				when OP_NEG   => 
				 ALUOP <= ALUOP_NEG;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '0';
				when OP_NOT   => 
				 ALUOP <= ALUOP_NOT;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '0';
				when OP_OR   => 
				 ALUOP <= ALUOP_OR;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '0';
				when OP_SLL   => 
				 ALUOP <= ALUOP_SLL;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '1';
				when OP_SLLV   => 
				 ALUOP <= ALUOP_SLL;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '0';
				when OP_SLT   => 
				 ALUOP <= ALUOP_LESS;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '0';
				when OP_SLTI   => 
				 ALUOP <= ALUOP_LESS;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '1';
				when OP_SLTU   => 
				 ALUOP <= ALUOP_LESSU;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '0';
				when OP_SLTUI   => 
				 ALUOP <= ALUOP_LESSU;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '1';
				when OP_SRA   => 
				 ALUOP <= ALUOP_SRA;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '1';
				when OP_SRAV   => 
				 ALUOP <= ALUOP_SRA;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '0';
				when OP_SRL   => 
				 ALUOP <= ALUOP_SRL;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '1';
				when OP_SRLV   => 
				 ALUOP <= ALUOP_SRL;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '0';
				when OP_SUBU   => 
				 ALUOP <= ALUOP_SUB;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '0';
				when OP_SW   => 
				 ALUOP <= ALUOP_ADD;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '1';
				when OP_SW_RS   => 
				 ALUOP <= ALUOP_ADD;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '1';
				when OP_SW_SP   => 
				 ALUOP <= ALUOP_ADD;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '1';
				when OP_XOR   => 
				 ALUOP <= ALUOP_XOR;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '0';
				when OP_NOP   => 
				 ALUOP <= ALUOP_REG1;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '0';
				when OP_INT1  =>
				 ALUOP <= ALUOP_ADD;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '1'; ---HERE USE PC
				when OP_INT2  =>
				 ALUOP <= ALUOP_SUB2;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '1'; --!!!!
				when OP_INT3  =>
				 ALUOP <= ALUOP_AND;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '1';
            when others => 
				 ALUOP <= ALUOP_REG1;
				 ALU_IN_A <= '0';
				 ALU_IN_B <= '0';
        end case;
    end process;

end Behavioral;

